import concurrent
import os
import socket
import sys
import platform
import subprocess
import ipaddress
from concurrent.futures import ThreadPoolExecutor


def scan_local_network(ip_range=None, timeout=1, max_threads=100):
    """
    扫描局域网中存在的 IP 地址

    参数:
        ip_range: 扫描的 IP 范围 (如 "192.168.1.0/24")
        timeout: 每个 IP 的等待时间 (秒)
        max_threads: 最大线程数
    """
    # 获取本地 IP 和默认范围
    if ip_range is None:
        ip_range = get_default_ip_range()

    # 生成要扫描的 IP 列表
    network = ipaddress.ip_network(ip_range, strict=False)
    ip_list = [str(ip) for ip in network.hosts()]  # 排除网络地址和广播地址

    print(f"Scanning {len(ip_list)} IPs in range {ip_range}...")

    # 使用多线程扫描
    active_ips = []
    with ThreadPoolExecutor(max_workers=max_threads) as executor:
        futures = {executor.submit(check_ip_active, ip, timeout): ip for ip in ip_list}
        for future in concurrent.futures.as_completed(futures):
            ip = futures[future]
            try:
                if future.result():
                    print(f"Active: {ip}")
                    active_ips.append(ip)
            except Exception as e:
                print(f"Error scanning {ip}: {str(e)}")

    print("\nScan completed!")
    print(f"Found {len(active_ips)} active devices:")
    for ip in sorted(active_ips, key=lambda ip: ipaddress.ip_address(ip)):
        print(f" - {ip}")

    return active_ips


def check_ip_active(ip, timeout=1):
    """检查单个 IP 是否活跃"""
    try:
        # Windows 系统
        if platform.system().lower() == "windows":
            command = ["ping", "-n", "1", "-w", str(timeout * 1000), ip]
            result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                                    creationflags=subprocess.CREATE_NO_WINDOW)
            return result.returncode == 0 and b"TTL=" in result.stdout

        # Linux/MacOS 系统
        else:
            command = ["ping", "-c", "1", "-W", str(timeout), ip]
            result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            return result.returncode == 0

    except Exception:
        return False


def get_default_ip_range():
    """获取本机 IP 并生成默认的 C 类网络范围"""
    try:
        # 获取本机 IP 地址
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        local_ip = s.getsockname()[0]
        s.close()

        # 生成 C 类网络范围 (如 192.168.1.0/24)
        ip_parts = local_ip.split('.')
        return f"{ip_parts[0]}.{ip_parts[1]}.{ip_parts[2]}.0/24"

    except Exception:
        return "192.168.1.0/24"  # 默认值


if __name__ == "__main__":
    # 使用示例
    active_ips = scan_local_network(timeout=0.5)